package com.tg.smsgw.ws;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintStream;
import java.sql.*;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import telsoft.dictionary.DictionaryNode;
import telsoft.sql.Database;
import telsoft.sql.OracleConnectionFactory;
import telsoft.util.StringUtil;
/**
 * <p>Title: </p>
 * <p>Description: </p>
 * <p>Copyright: Copyright (c) 2003</p>
 * <p>Company: FSS-FPT</p>
 * @author Thai Hoang Hiep
 * @version 1.0
 */

public class AppServer
{
	////////////////////////////////////////////////////////
	// Constant
	////////////////////////////////////////////////////////
	public static final String SYSTEM_PASSWORD_FILE = "system.pwd";
	////////////////////////////////////////////////////////
	// Variables
	////////////////////////////////////////////////////////
	private static telsoft.dictionary.Dictionary dic = new telsoft.dictionary.Dictionary();
//	private static OracleConnectionFactory pool = null;
	////////////////////////////////////////////////////////
	// For pool connection
	////////////////////////////////////////////////////////
	private static OracleConnectionFactory portalConnectionPool = null;
	private static OracleConnectionFactory linkConnectionPool = null;

	////////////////////////////////////////////////////////
	// Static initialize
	////////////////////////////////////////////////////////
	static
	{
		try
		{
			loadConfig("/com/tg/smsgw/ws/ServerConfig.txt");
			createConnectionPool();
		}
		catch(Exception e)
		{
                    PrintStream ps = null;
                    try {
                        ps = new PrintStream(new File("service.init.log"));
                        e.printStackTrace(ps);
                    } catch (FileNotFoundException ex) {
                        Logger.getLogger(AppServer.class.getName()).log(Level.SEVERE, null, ex);
                    }
                    finally{
                        if(ps!=null)
                            ps.close();
                    }
		}
	}

	////////////////////////////////////////////////////////
	public static void createConnectionPool() throws Exception
	{
                String strDatabaseNode = getDictionaryNode("Connection.Default").getValue();
		DictionaryNode dbNode = getDictionaryNode("Connection." + strDatabaseNode);
		portalConnectionPool =
			 new OracleConnectionFactory(dbNode.getChild("Url").getValue(),
										  dbNode.getChild("UserName").getValue(),
										  dbNode.getChild("Password").getValue(),
										  Integer.parseInt(dbNode.getChild("MaxConnection").getValue()),
										  Integer.parseInt(dbNode.getChild("MinConnection").getValue()),
										  OracleConnectionFactory.DYNAMIC_SCHEME );
	}

	////////////////////////////////////////////////////////
	/**
	 * Load parameter from resource
	 * @param strFileName path to config file
	 * @throws Exception
	 * @author Thai Hoang Hiep
	 */
	////////////////////////////////////////////////////////
	public static void loadConfig(String strFileName) throws Exception
	{
		dic.load(AppServer.class.getResourceAsStream(strFileName));
	}
	////////////////////////////////////////////////////////
	/**
	 *
	 * @param nd DictionaryNode
	 * @param str String
	 * @return Vector
	 */
	////////////////////////////////////////////////////////
	public static Vector getParamList(DictionaryNode nd,String str)
	{
		Vector vtReturn = new Vector();
		if(nd != null && nd.getChildList() != null)
		{
			Vector vt = nd.getChildList();
			for(int iIndex = 0;iIndex < vt.size();iIndex++)
			{
				DictionaryNode ndChild = (DictionaryNode)vt.elementAt(iIndex);
				String strChildName = StringUtil.nvl(ndChild.mstrName,"");
				Vector vtRow = new Vector();
				if(str.equals(""))
				{
					vtRow.addElement(strChildName);
					vtRow.addElement(StringUtil.nvl(ndChild.mstrValue,""));
					vtReturn.addElement(vtRow);
					vtReturn.addAll(getParamList(ndChild,strChildName));
				}
				else
				{
					vtRow.addElement(str + "." + strChildName);
					vtRow.addElement(StringUtil.nvl(ndChild.mstrValue,""));
					vtReturn.addElement(vtRow);
					vtReturn.addAll(getParamList(ndChild,str + "." + strChildName));
				}
			}
		}
		return vtReturn;
	}
	////////////////////////////////////////////////////////
	public static Vector getParamList()
	{
		return getParamList(dic.mndRoot,"");
	}
	////////////////////////////////////////////////////////
	/**
	 * Get parameter from server config
	 * @param strKey String
	 * @return String
	 */
	////////////////////////////////////////////////////////
	public static String getParam(String strKey)
	{
		return dic.getString(strKey);
	}
	////////////////////////////////////////////////////////
	/**
	 *
	 * @param strKey String
	 * @param strValue String
	 * @throws Exception
	 */
	////////////////////////////////////////////////////////
	public static void setParam(String strKey,String strValue) throws Exception
	{
		if(strKey.equals("DefaultDatabase"))
		{
			DictionaryNode nd = getDictionaryNode("Connection." + strValue);
			if(nd == null)
			{
				nd = getDictionaryNode("Connection");
				Vector vtConnection = nd.getChildList();
				String strChildList = "";
				for(int iIndex = 0;iIndex < vtConnection.size();iIndex++)
					strChildList += ((DictionaryNode)vtConnection.elementAt(iIndex)).mstrName + ",";
				if(!strChildList.equals(""))
					strChildList = strChildList.substring(0,strChildList.length() - 1);
				throw new Exception("Database '" + strValue + "' was not declared. Available database is: " + strChildList);
			}
		}
		DictionaryNode nd = getDictionaryNode(strKey);
		if(nd == null)
			throw new Exception("Parameter '" + strKey + "' not found");
		nd.mstrValue = StringUtil.nvl(strValue,"");
	}
	////////////////////////////////////////////////////////
	/**
	 * Get a dictionary node from server config
	 * @param node String
	 * @return DictionaryNode
	 */
	////////////////////////////////////////////////////////
	public static DictionaryNode getDictionaryNode(String node)
	{
		return dic.getNode(node);
	}
	////////////////////////////////////////////////////////
	/**
	 * Open conection to database
	 * @return connection created
	 * @throws java.lang.Exception
	 * @author Thai Hoang Hiep
	 */
	////////////////////////////////////////////////////////
	public static Connection getConnection() throws Exception
	{
		return portalConnectionPool.getConnection();
		//return pool.getConnection();
	}

	////////////////////////////////////////////////////////
	public static Connection getRestrictedConnection() throws Exception
	{
		// User for link connection
		return linkConnectionPool.getConnection();
	}

	////////////////////////////////////////////////////////
	/**
	 * Check priviledge
	 * @param strUserName String
	 * @param strModuleName String
	 * @param strRight String
	 * @throws Exception
	 */
	////////////////////////////////////////////////////////
	public static void checkPrivilege(String strUserName,String strModuleName,String strRight) throws Exception
	{
		AppAuthenticator authenticator = new AppAuthenticator();
		Connection cn = null;
		try
		{
			cn = getConnection();
			authenticator.setConnection(cn);
			authenticator.checkPrivilege(strUserName,strModuleName,strRight);
		}
		finally
		{
			Database.closeObject(cn);
		}
	}
	////////////////////////////////////////////////////////
	/**
	 * Verrify password
	 * @param cn Connection
	 * @param strUserName String
	 * @param strPassword String
	 * @return String
	 * @throws Exception
	 */
	////////////////////////////////////////////////////////
	public static String verifyPassword(Connection cn,String strUserName,String strPassword) throws Exception
	{
		AppAuthenticator authenticator = new AppAuthenticator();
		authenticator.setConnection(cn);
		return authenticator.verifyPassword(strUserName,strPassword);
	}
	////////////////////////////////////////////////////////
	/**
	 * Verrify password
	 * @param strUserName String
	 * @param strPassword String
	 * @return String
	 * @throws Exception
	 */
	////////////////////////////////////////////////////////
	public static String verifyPassword(String strUserName,String strPassword) throws Exception
	{
		Connection cn = null;
		try
		{
			cn = getConnection();
			return verifyPassword(cn,strUserName,strPassword);
		}
		finally
		{
			Database.closeObject(cn);
		}
	}
	////////////////////////////////////////////////////////
	/**
	 * Close Database Link
	 */
	////////////////////////////////////////////////////////
	public static void closeDatabaseLink(Connection cn,String strDatabaseLink)
	{
		try
		{
			cn.commit();
		}
		catch(Exception e)
		{
		}
		try
		{
			Statement s = cn.createStatement();
			s.executeUpdate("ALTER SESSION CLOSE DATABASE LINK " + strDatabaseLink);
			Database.closeObject(s);
		}
		catch(Exception e1)
		{
			e1.printStackTrace();
		}
	}

}
